<template>
    <div class="lua-editor-container">
        <!-- 工具栏 -->
        <Toolbar
            :can-undo="canUndoFunc"
            :can-redo="canRedoFunc"
            :current-theme="currentTheme"
            :current-font-size="currentFontSize"
            @new-file="handleNewFile"
            @save-file="handleSaveFile"
            @load-file="handleLoadFile"
            @undo="handleUndo"
            @redo="handleRedo"
            @template-select="handleTemplateSelect"
            @theme-change="handleThemeChange"
            @font-size-change="handleFontSizeChange"
            @run-code="handleRunCode"
        />

        <!-- 编辑器主体 -->
        <div class="editor-main">
            <div class="editor-wrapper">
                <div v-if="showError" class="error-message">
                    <h4>编辑器加载失败</h4>
                    <p>{{ errorMessage }}</p>
                    <p>请检查浏览器控制台获取详细错误信息。</p>
                </div>
                <div v-else ref="aceEditor" class="ace-editor" />
            </div>

            <!-- 右侧垂直Tab栏 -->
            <div class="right-sidebar">
                <!-- 垂直Tab按钮 -->
                <div class="tab-buttons">
                    <div
                        v-for="tab in rightTabs"
                        :key="tab.key"
                        :class="['tab-button', { active: activeRightTab === tab.key }]"
                        :title="tab.label"
                        @click="handleRightTabClick(tab.key)"
                    >
                        <span class="tab-text">{{ tab.label }}</span>
                    </div>
                </div>

                <!-- 侧边面板 -->
                <transition name="slide">
                    <div v-if="showRightPanel" class="side-panel">
                        <div class="panel-header">
                            <span class="panel-title">{{ currentTabLabel }}</span>
                            <a-icon
                                type="close"
                                class="close-icon"
                                @click="closeRightPanel"
                            />
                        </div>
                        <div class="panel-content">
                            <!-- 全部预览 -->
                            <PreviewPanel
                                v-if="activeRightTab === 'preview'"
                                :content="editorPreviewContent"
                                @update-completions="handleUpdateCompletions"
                            />

                            <!-- MQTT -->
                            <MqttPanel
                                v-if="activeRightTab === 'mqtt'"
                                ref="mqttPanel"
                                @update-completions="handleUpdateCompletions"
                            />
                        </div>
                    </div>
                </transition>
            </div>
        </div>

        <!-- 状态栏 -->
        <StatusBar
            :file-name="fileName"
            :is-modified="isModified"
            :last-saved="lastSaved"
            :current-line="currentLine"
            :current-column="currentColumn"
            :total-lines="totalLines"
            :font-size="currentFontSize"
        />

        <!-- 文件选择对话框 -->
        <input
            ref="fileInput"
            type="file"
            accept=".lua,.txt"
            style="display: none;"
            @change="handleFileLoad"
        >
    </div>
</template>

<script>
import { Modal } from 'ant-design-vue'
import ace from 'ace-builds'
import { defaultConfig, luaCompletions } from './utils/aceConfig'
import { getTemplate } from './utils/luaTemplates'
import editorMixin from './mixins/editorMixin'
import Toolbar from './components/Toolbar.vue'
import StatusBar from './components/StatusBar.vue'
import PreviewPanel from './panels/PreviewPanel.vue'
import MqttPanel from './panels/MqttPanel.vue'

export default {
    name: 'LuaEditor',
    components: {
        Toolbar,
        StatusBar,
        PreviewPanel,
        MqttPanel
    },
    mixins: [editorMixin],
    data() {
        return {
            currentTheme: defaultConfig.theme,
            currentFontSize: defaultConfig.fontSize,
            showError: false,
            errorMessage: '',
            // 响应式数据来跟踪撤销重做状态 - 使用不同的名称避免冲突
            undoAvailable: false,
            redoAvailable: false,
            keyName: 'lua_script',
            // 动态补全项列表
            dynamicCompletions: [],
            // 右侧Tab栏相关
            activeRightTab: '',
            showRightPanel: false,
            rightTabs: [
                { key: 'preview', label: '数据监控全部预览' },
                { key: 'mqtt', label: 'MQTT' }
            ]
        }
    },
    computed: {
        // 计算属性：是否可以撤销 - 暴露给模板使用
        canUndoFunc() {
            return this.undoAvailable
        },
        // 计算属性：是否可以重做 - 暴露给模板使用
        canRedoFunc() {
            return this.redoAvailable
        },
        // 当前Tab标签
        currentTabLabel() {
            const tab = this.rightTabs.find(t => t.key === this.activeRightTab)
            return tab ? tab.label : ''
        },
        // 编辑器预览内容
        editorPreviewContent() {
            return this.editor ? this.editor.getValue() : ''
        }
    },
    mounted() {
        this.initEditor()
        this.setupAutoSave()
    },
    beforeDestroy() {
        if (this.editor) {
            this.editor.destroy()
        }
        if (this.autoSaveTimer) {
            clearInterval(this.autoSaveTimer)
        }
    },
    methods: {
        // 初始化编辑器
        async initEditor() {
            try {
                // 等待DOM渲染完成
                await this.$nextTick()

                console.log('开始初始化Lua编辑器...')

                // 检查容器元素
                if (!this.$refs.aceEditor) {
                    throw new Error('编辑器容器未找到')
                }

                // 创建编辑器实例
                this.editor = ace.edit(this.$refs.aceEditor)
                console.log('Ace编辑器实例创建成功')

                // 基础配置
                this.editor.setTheme('ace/theme/monokai')
                this.editor.session.setMode('ace/mode/lua')
                this.editor.setFontSize(14)
                this.editor.setShowPrintMargin(true)
                this.editor.setPrintMarginColumn(80)
                this.editor.renderer.setShowGutter(true)
                this.editor.setHighlightActiveLine(true)
                this.editor.session.setTabSize(2)
                this.editor.session.setUseSoftTabs(true)

                // 启用自动补全
                this.editor.setOptions({
                    enableBasicAutocompletion: true,
                    enableLiveAutocompletion: true,
                    enableSnippets: true
                })

                console.log('编辑器配置完成')

                // 设置自定义补全
                this.setupAutoCompletion()

                // 初始化事件监听
                this.initEditorEvents()

                // 设置默认内容
                this.setEditorContent(getTemplate('basic').code)

                // 聚焦编辑器
                this.editor.focus()

                // 更新撤销重做状态
                this.updateUndoRedoState()

                // 加载文件
                this.loadFile()

                console.log('Lua编辑器初始化成功!')
            } catch (error) {
                console.error('编辑器初始化失败:', error)
                this.showError = true
                this.errorMessage = error.message || '编辑器加载失败'
            }
        },

        // 提供给父组件调用的重新加载方法
        reloadData() {
            console.log('🔄 [LuaEditor] 重新加载数据')
            this.loadFile()
        },

        // 设置自动补全
        setupAutoCompletion() {
            try {
                const langTools = ace.require('ace/ext/language_tools')

                // 添加自定义补全器
                const luaCompleter = {
                    getCompletions: (editor, session, pos, prefix, callback) => {
                        // 合并静态补全和动态补全
                        const allCompletions = [...luaCompletions, ...this.dynamicCompletions]
                        
                        // 如果没有输入前缀，返回所有补全项
                        if (!prefix) {
                            callback(null, allCompletions)
                            return
                        }

                        // 模糊匹配：支持子序列匹配（如 "fun" 匹配 "function"）
                        const lowerPrefix = prefix.toLowerCase()
                        const filtered = allCompletions.filter(item => {
                            const caption = item.caption.toLowerCase()
                            // 1. 优先匹配开头
                            if (caption.startsWith(lowerPrefix)) {
                                item.matchScore = 100
                                return true
                            }
                            // 2. 包含匹配
                            if (caption.includes(lowerPrefix)) {
                                item.matchScore = 50
                                return true
                            }
                            // 3. 子序列匹配（如 "fun" -> "function"）
                            let prefixIndex = 0
                            for (let i = 0; i < caption.length && prefixIndex < lowerPrefix.length; i++) {
                                if (caption[i] === lowerPrefix[prefixIndex]) {
                                    prefixIndex++
                                }
                            }
                            if (prefixIndex === lowerPrefix.length) {
                                item.matchScore = 30
                                return true
                            }
                            return false
                        })

                        // 按匹配度和原始分数排序
                        filtered.sort((a, b) => {
                            const scoreA = (a.matchScore || 0) + (a.score || 0)
                            const scoreB = (b.matchScore || 0) + (b.score || 0)
                            return scoreB - scoreA
                        })

                        callback(null, filtered)
                    }
                }

                langTools.addCompleter(luaCompleter)
                console.log('自动补全设置完成，支持动态添加')
            } catch (error) {
                console.warn('自动补全设置失败:', error)
                // 不阻止编辑器初始化，只是没有自定义补全功能
            }
        },

        // 设置自动保存
        setupAutoSave() {
            this.autoSaveTimer = setInterval(() => {
                if (this.isModified && this.fileName) {
                    this.autoSave()
                }
            }, 30000) // 30秒自动保存
        },

        // 自动保存
        autoSave() {
            const content = this.getEditorContent()
            localStorage.setItem(`lua_editor_${this.fileName}`, content)
            console.log('自动保存完成')
        },

        // 更新撤销重做状态
        updateUndoRedoState() {
            if (this.editor) {
                this.undoAvailable = this.editor.session.getUndoManager().hasUndo()
                this.redoAvailable = this.editor.session.getUndoManager().hasRedo()
            }
        },

        // 重写编辑器事件初始化
        initEditorEvents() {
            if (!this.editor) return

            // 调用混入的方法
            editorMixin.methods.initEditorEvents.call(this)

            // 添加额外的事件监听
            this.editor.on('change', () => {
                this.updateUndoRedoState()
            })
        },

        // 处理新建文件
        handleNewFile() {
            this.$confirm({
                title: '确认新建文件',
                content: '当前文件未保存的更改将丢失，确认新建文件吗？',
                onOk: () => {
                    this.setEditorContent(getTemplate('basic').code)
                    this.setFileName('')
                    this.isModified = false
                }
            })
        },

        async loadFile() {
            try {
                const res = await this.$tabManager.edge.getLuaScript(this.keyName)
                console.log('🔍 [LuaEditor] 加载文件', res)
                if (res.code === 0) {
                    this.setEditorContent(res.data)
                    this.setFileName(res.data.Description)
                } else {
                    this.setEditorContent(getTemplate('basic').code)
                    this.setFileName('')
                }
            } catch (error) {
                console.error('🔍 [LuaEditor] 加载文件失败', error)
            }
        },

        // 处理保存文件
        async handleSaveFile() {
            const content = this.getEditorContent()
            const data = {
                Key: this.keyName,
                Value: content,
                Description: this.fileName
            }
            const res = await this.$tabManager.edge.saveLuaScript(JSON.stringify(data))
            if (res.code === 0) {
                this.$message.success('文件保存成功')
            } else {
                this.$message.error('文件保存失败')
            }
        },

        // 处理加载文件
        handleLoadFile() {
            this.$refs.fileInput.click()
        },

        // 处理文件加载
        handleFileLoad(event) {
            const file = event.target.files[0]
            if (!file) return

            const reader = new FileReader()
            reader.onload = e => {
                this.setEditorContent(e.target.result)
                this.setFileName(file.name)
                this.$message.success('文件加载成功')
            }
            reader.readAsText(file)
        },

        // 处理撤销
        handleUndo() {
            this.undo()
            this.updateUndoRedoState()
        },

        // 处理重做
        handleRedo() {
            this.redo()
            this.updateUndoRedoState()
        },

        // 处理模板选择
        handleTemplateSelect(templateKey) {
            const template = getTemplate(templateKey)

            this.$confirm({
                title: '确认使用模板',
                content: `确认使用"${template.name}"模板吗？当前内容将被替换。`,
                onOk: () => {
                    this.setEditorContent(template.code)
                    this.$message.success(`已应用模板：${template.name}`)
                }
            })
        },

        // 处理主题变更
        handleThemeChange(theme) {
            this.currentTheme = theme
            this.editor.setTheme(theme)
        },

        // 处理字体大小变更
        handleFontSizeChange(fontSize) {
            this.currentFontSize = fontSize
            this.editor.setFontSize(fontSize)
        },

        // 处理运行代码
        async handleRunCode() {
            try {
                const code = this.getEditorContent()
                const res = await this.$tabManager.edge.runLuaScript(code)
                console.log('Lua脚本运行返回结果:', res)
                
                if (!res) {
                    throw new Error('运行结果为空')
                }

                if (res.IsSuccess && res.code === 0) {
                    Modal.success({
                        title: '代码运行成功',
                        content: res.data || '执行成功，但没有返回数据'
                    })
                } else {
                    const errorMsg = res.message || '未知错误'
                    Modal.error({
                        title: '代码运行失败',
                        content: errorMsg
                    })
                }
            } catch (error) {
                console.error('运行Lua脚本时发生错误:', error)
                Modal.error({
                    title: '代码运行错误',
                    content: error.message || '运行时发生未知错误'
                })
            }
        },

        /**
         * 添加单个补全项
         * @param {Object} completion - 补全项对象
         * @param {string} completion.caption - 显示的文本
         * @param {string} completion.value - 插入的值
         * @param {string} completion.meta - 类别标签（支持中文）
         * @param {number} completion.score - 优先级分数（越高越优先）
         * @param {string} completion.docHTML - 悬停提示（支持HTML）
         * @example
         * this.addCompletion({
         *   caption: 'deviceName',
         *   value: 'deviceName',
         *   meta: '设备',
         *   score: 1500,
         *   docHTML: '<b>deviceName</b><br/>设备名称'
         * })
         */
        addCompletion(completion) {
            // 检查是否已存在相同的补全项
            const exists = this.dynamicCompletions.some(item => item.caption === completion.caption)
            if (!exists) {
                this.dynamicCompletions.push(completion)
            } else {
                console.warn(`⚠️ 补全项已存在: ${completion.caption}`)
            }
        },

        /**
         * 批量添加补全项
         * @param {Array} completions - 补全项数组
         */
        addCompletions(completions) {
            completions.forEach(completion => {
                this.addCompletion(completion)
            })
        },

        /**
         * 删除指定的补全项
         * @param {string} caption - 要删除的补全项的 caption
         */
        removeCompletion(caption) {
            const index = this.dynamicCompletions.findIndex(item => item.caption === caption)
            if (index !== -1) {
                this.dynamicCompletions.splice(index, 1)
                console.log(`🗑️ 删除补全项: ${caption}`)
            }
        },

        /**
         * 按类别删除补全项
         * @param {string} meta - 类别标签
         */
        removeCompletionsByCategory(meta) {
            const before = this.dynamicCompletions.length
            this.dynamicCompletions = this.dynamicCompletions.filter(item => item.meta !== meta)
            const removed = before - this.dynamicCompletions.length
            console.log(`🗑️ 删除类别"${meta}"的补全项，共${removed}个`)
        },

        /**
         * 清空所有动态补全项
         */
        clearDynamicCompletions() {
            this.dynamicCompletions = []
            console.log('🗑️ 清空所有动态补全项')
        },

        /**
         * 获取当前所有动态补全项
         * @returns {Array}
         */
        getDynamicCompletions() {
            return this.dynamicCompletions
        },

        /**
         * 更新指定的补全项
         * @param {string} caption - 要更新的补全项的 caption
         * @param {Object} newData - 新的数据
         */
        updateCompletion(caption, newData) {
            const index = this.dynamicCompletions.findIndex(item => item.caption === caption)
            if (index !== -1) {
                this.dynamicCompletions[index] = { ...this.dynamicCompletions[index], ...newData }
                console.log(`✏️ 更新补全项: ${caption}`)
            }
        },

        // ============= 右侧Tab栏相关方法 =============

        /**
         * 处理右侧Tab点击
         * @param {string} tabKey - Tab的key
         */
        handleRightTabClick(tabKey) {
            if (this.activeRightTab === tabKey) {
                // 如果点击的是已激活的tab，则关闭面板
                this.closeRightPanel()
            } else {
                // 否则切换到新的tab并显示面板
                this.activeRightTab = tabKey
                this.showRightPanel = true
                // 加载对应的数据
                this.loadTabData(tabKey)
            }
        },

        /**
         * 关闭右侧面板
         */
        closeRightPanel() {
            this.showRightPanel = false
            this.activeRightTab = ''
        },

        /**
         * 根据tab加载对应的数据
         * @param {string} tabKey - Tab的key
         */
        loadTabData(tabKey) {
            // 各个面板组件会在自己的 mounted 钩子中加载数据
            // 这里不需要额外操作
            console.log(`切换到Tab: ${tabKey}`)
        },

        /**
         * 处理插入变量
         * @param {string} variableName - 变量名
         */
        handleInsertVariable(variableName) {
            if (this.editor) {
                this.editor.insert(variableName)
                this.editor.focus()
                this.$message.success(`已插入变量: ${variableName}`)
            }
        },

        /**
         * 处理选中设备
         * @param {Object} device - 设备对象
         */
        handleDeviceSelect(device) {
            console.log('选中设备:', device)
            this.$message.info(`选中设备: ${device.name}`)
            // 可以在这里进行其他操作，比如加载设备相关的变量等
        },

        /**
         * 处理选中端口
         * @param {Object} port - 端口对象
         */
        handlePortSelect(port) {
            console.log('选中端口:', port)
            this.$message.info(`选中端口: ${port.name}`)
            // 可以在这里进行其他操作
        },

        /**
         * 处理更新补全项
         * 从 PreviewPanel 接收端口/设备/变量数据，从 MqttPanel 接收 MQTT 名称
         * @param {Array} completions - 补全项数组
         */
        handleUpdateCompletions(completions) {
            console.log('📥 [LuaEditor] 接收补全数据，共', completions.length, '个')
            
            // 检测补全数据的类型，智能清除对应类别
            const categories = new Set(completions.map(item => item.meta))
            
            // 如果包含端口/设备，清除旧的端口、设备补全项
            if (categories.has('端口') || categories.has('设备')) {
                this.removeCompletionsByCategory('端口')
                this.removeCompletionsByCategory('设备')
            }
            
            // 如果包含变量类别，清除所有变量类别（因为变量类别是动态的，如"变量(string)"）
            const hasVariableCategory = Array.from(categories).some(cat => cat && cat.startsWith('变量'))
            if (hasVariableCategory) {
                this.dynamicCompletions = this.dynamicCompletions.filter(item => {
                    return !item.meta || !item.meta.startsWith('变量')
                })
            }
            
            // 如果包含 MQTT 类别，清除旧的 MQTT 补全项
            if (categories.has('MQTT')) {
                this.removeCompletionsByCategory('MQTT')
            }
            
            // 添加新的补全项
            this.addCompletions(completions)
            
            console.log('✅ [LuaEditor] 补全项更新完成，当前动态补全项数量:', this.dynamicCompletions.length)
            
            // 可选：显示提示消息
            const categoryList = Array.from(categories).join('、')
            this.$message.success(`已更新 ${completions.length} 个${categoryList}补全项`, 2)
        }
    }
}
</script>

<style scoped>
.lua-editor-container {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: #fff;
}
.editor-main {
    flex: 1;
    display: flex;
    position: relative;
    overflow: hidden;
    min-height: 0;
}
.editor-wrapper {
    flex: 1;
    position: relative;
    overflow: hidden;
    min-height: 0; /* 防止flex子元素溢出 */
}
.ace-editor {
    width: 100%;
    height: 100%;
    font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
}
.error-message {
    padding: 20px;
    background: #fff2f0;
    border: 1px solid #ffccc7;
    border-radius: 4px;
    margin: 20px;
}
.error-message h4 {
    color: #cf1322;
    margin: 0 0 10px 0;
}
.error-message p {
    color: #595959;
    margin: 5px 0;
}

/* 右侧侧边栏 */
.right-sidebar {
    display: flex;
    position: relative;
    background: #f5f5f5;
}

/* 垂直Tab按钮区域 */
.tab-buttons {
    display: flex;
    flex-direction: column;
    background: #e8e8e8;
    border-left: 1px solid #d9d9d9;
    min-width: 36px;
    z-index: 10;
}
.tab-button {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px 8px;
    cursor: pointer;
    border-bottom: 1px solid #d9d9d9;
    background: #fafafa;
    transition: all 0.3s;
    position: relative;
}
.tab-button:hover {
    background: #e6f7ff;
}
.tab-button.active {
    background: #1890ff;
    color: #fff;
}
.tab-button.active::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: #0050b3;
}
.tab-text {
    writing-mode: vertical-rl;
    text-orientation: mixed;
    font-size: 13px;
    white-space: nowrap;
    user-select: none;
}

/* 侧边面板 */
.side-panel {
    width: 320px;
    background: #fff;
    border-left: 1px solid #d9d9d9;
    display: flex;
    flex-direction: column;
    box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
    z-index: 9;
}
.panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    background: #fafafa;
    border-bottom: 1px solid #e8e8e8;
}
.panel-title {
    font-size: 14px;
    font-weight: 500;
    color: #262626;
}
.close-icon {
    cursor: pointer;
    font-size: 14px;
    color: #8c8c8c;
    transition: color 0.3s;
}
.close-icon:hover {
    color: #262626;
}
.panel-content {
    flex: 1;
    overflow-y: auto;
    padding: 16px;
}

/* 滑入滑出动画 */
.slide-enter-active,
.slide-leave-active {
    transition: all 0.3s ease;
}
.slide-enter-from {
    transform: translateX(100%);
    opacity: 0;
}
.slide-leave-to {
    transform: translateX(100%);
    opacity: 0;
}
.slide-enter-to,
.slide-leave-from {
    transform: translateX(0);
    opacity: 1;
}

/* 滚动条样式 */
.panel-content::-webkit-scrollbar {
    width: 6px;
}
.panel-content::-webkit-scrollbar-track {
    background: #f5f5f5;
}
.panel-content::-webkit-scrollbar-thumb {
    background: #d9d9d9;
    border-radius: 3px;
}
.panel-content::-webkit-scrollbar-thumb:hover {
    background: #bfbfbf;
}
</style>